package com.fm.financemanage.service;


import com.fm.financemanage.component.RedisComponent;
import com.fm.financemanage.component.TokenComponent;
import com.fm.financemanage.constant.ResponseEnum;
import com.fm.financemanage.constant.UserConstants;
import com.fm.financemanage.exception.BusinessException;
import com.fm.financemanage.mapper.AccountantMapper;
import com.fm.financemanage.mapper.SysMenuMapper;
import com.fm.financemanage.mapper.SysUserMapper;
import com.fm.financemanage.mapper.SysUserRoleMapper;
import com.fm.financemanage.model.dto.UserDto;
import com.fm.financemanage.model.po.Accountant;
import com.fm.financemanage.model.po.SysMenu;
import com.fm.financemanage.model.po.SysUser;
import com.fm.financemanage.model.po.SysUserRole;
import com.fm.financemanage.model.vo.SysUserVo;
import com.fm.financemanage.utils.MessageDigestUtil;
import com.fm.financemanage.utils.TextUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @version V1.0
 */
@Service
public class SysUserService {

    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    SysUserRoleMapper userRoleMapper;
    @Resource
    private SysMenuMapper sysMenuMapper;
    @Resource
    private AccountantMapper accountantMapper;

    @Autowired
    private TokenComponent tokenComponent;
    @Autowired
    private RedisComponent redisComponent;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

//    @Value("${info.version}")
//    private String version;

    /**
     * 根据用户的手机或者邮箱查询
     *
     * @return 返回用户列表
     **/
    public List<SysUserVo> getAll(String keyword, Integer page, Integer limit) {
        return sysUserMapper.getByCondition(keyword, page, limit);
    }

    public int count(String keyword) {
        return sysUserMapper.countByCondition(keyword);
    }

    //检查是否存在id不同账号相同的账号
    public String checkLoginNameIsMe(String loginName, Long id) {
        int count = sysUserMapper.checkLoginNameUnique(loginName, id);
        if (count > 0) {
            return UserConstants.USER_NAME_NOT_UNIQUE;
        }
        return UserConstants.USER_NAME_UNIQUE;
    }

    public String checkLoginNameUnique(String loginName) {
        int count = sysUserMapper.checkLoginNameUnique(loginName, null);
        if (count > 0) {
            return UserConstants.USER_NAME_NOT_UNIQUE;
        }
        return UserConstants.USER_NAME_UNIQUE;
    }

    public String checkPhoneUnique(SysUserVo user) {
        long userId = TextUtil.isEmpty(user.getId()) ? -1L : user.getId();
        SysUser info = sysUserMapper.checkPhoneUnique(user.getPhonenumber());
        if (!TextUtil.isEmpty(info) && info.getId() != userId) {
            return UserConstants.USER_PHONE_NOT_UNIQUE;
        }
        return UserConstants.USER_PHONE_UNIQUE;
    }

    /**
     * 校验email是否唯一
     *
     * @param user 用户信息
     */

    public String checkEmailUnique(SysUserVo user) {
        long userId = TextUtil.isEmpty(user.getId()) ? -1L : user.getId();
        SysUser info = sysUserMapper.checkEmailUnique(user.getEmail());
        if (!TextUtil.isEmpty(info) && info.getId() != userId) {
            return UserConstants.USER_EMAIL_NOT_UNIQUE;
        }
        return UserConstants.USER_EMAIL_UNIQUE;
    }

    public boolean checkUserAllowed(Long id) {
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(id);
        return UserConstants.SYSTEM_SUPER_USER_TYPE.equals(sysUser.getUserType());

    }

    @Transactional(rollbackFor = Exception.class)
    public void insertUser(SysUserVo user) {
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setUserType(UserConstants.SYSTEM_USER_TYPE);
        user.setHasDeleted("0");
        SysUser build = SysUserVo.build(user);
        sysUserMapper.insertSelective(build);
        insertUserRole(build.getId(), user.getRoleIds());

    }

    /**
     * 增加用户对应的角色
     **/
    public void insertUserAuth(Long userId, Long[] roleIds) {
        userRoleMapper.deleteUserRoleByUserId(userId);
        insertUserRole(userId, roleIds);
    }

    /**
     * 修改用户
     **/
    public void updateUser(SysUserVo user) {
        // 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(user.getId());
        // 新增用户与角色管理
        insertUserRole(user.getId(), user.getRoleIds());

        sysUserMapper.updateByPrimaryKeySelective(SysUserVo.build(user));
    }

    /**
     * 新增用户角色信息
     */
    private void insertUserRole(Long userId, Long[] roleIds) {
        if (roleIds != null) {
            // 新增用户与角色管理
            List<SysUserRole> list = new ArrayList<>();
            for (Long roleId : roleIds) {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(userId);
                ur.setRoleId(roleId);
                list.add(ur);
            }
            if (list.size() > 0) {
                userRoleMapper.batchUserRole(list);
            }
        }
    }

    /**
     * 删除用户信息
     *
     * @return 结果
     */

    @Transactional(rollbackFor = Exception.class)
    public int deleteUserByIds(Long id) {

        if (checkUserAllowed(id)) {
            return -1;
        }
        Long[] ids = {id};
        // 删除用户与角色关联
        userRoleMapper.deleteUserRole(ids);

        return sysUserMapper.deleteUserByIds(ids);
    }

    /**
     * 重置密码
     *
     * @return boolean
     **/
    public boolean resetUserPwd(Long id, String password) {
        try {
            SysUser sysUser = sysUserMapper.selectByPrimaryKey(id);
            boolean b = checkUserAllowed(id);
            if (b) {
                return false;
            }
            if (sysUser != null) {
                sysUser.setPassword(MessageDigestUtil.encryptMD5(password.getBytes()));
                sysUser.setUpdateTime(LocalDateTime.now());
                sysUser.setPwdUpdateDate(LocalDateTime.now());
                sysUserMapper.updateByPrimaryKeySelective(sysUser);
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;

    }

    /**
     * 根据id查询用户
     *
     * @return boolean
     **/
    public SysUser getUser(Long id) {
        try {
            return sysUserMapper.selectByPrimaryKey(id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 用户登录
     */

    public Map<String, Object> login(UserDto dto) {

        SysUser name = sysUserMapper.findByName(dto.getLoginname());
        if (name == null || name.getId() == null) {
            return null;
        }
        SysUserVo sysUser = new SysUserVo();
        sysUser.setLoginName(name.getLoginName());
        sysUser.setAvatar(name.getAvatar());
        sysUser.setUserName(name.getUserName());
        sysUser.setSex(name.getSex());
        sysUser.setPhonenumber(name.getPhonenumber());
        sysUser.setId(name.getId());
        sysUser.setUpdateTime(LocalDateTime.now());
        sysUser.setUserType(name.getUserType());
        // 获取token
        String token = tokenComponent.getByUser(sysUser);
        // 存入redis 设置过期时间一天

        redisTemplate.opsForValue().set("Authorization:" + token, 1, 86400, TimeUnit.SECONDS);
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", sysUser);
        //
        List<SysMenu> menuList;
        if (!TextUtil.isEmpty(name.getUserType()) && name.getUserType().equals(UserConstants.SYSTEM_SUPER_USER_TYPE)) {
            menuList = sysMenuMapper.selectMenuAll();
        } else {
            menuList = sysMenuMapper.selectMenuAllByUserId(sysUser.getId());
        }
        map.put("menuList", menuList);
        map.put("version", "1.4.0");
        return map;
    }

    /**
     * 退出登录
     **/
    public void logout(String token) {
        if (!TextUtil.isEmpty(token)) {
            redisTemplate.delete("Authorization:" + token);
        }
    }

    /**
     * 用户登录
     *
     * @param username 账号名
     * @return 用户信息
     */

    public SysUserVo findByName(String username) {

        // 根据用户名获取用户信息
        SysUser user = sysUserMapper.findByName(username);
        if (user == null || user.getId() == null) {
            return null;
        }
        SysUserVo sysUser = new SysUserVo();
        sysUser.setLoginName(user.getLoginName());
        sysUser.setAvatar(user.getAvatar());
        sysUser.setUserName(user.getUserName());
        sysUser.setSex(user.getSex());
        sysUser.setPhonenumber(user.getPhonenumber());
        sysUser.setId(user.getId());
        sysUser.setUserType(user.getUserType());
        sysUser.setPassword(user.getPassword());
        List<SysMenu> menuList;
        if (!TextUtil.isEmpty(user.getUserType()) && user.getUserType().equals(UserConstants.SYSTEM_SUPER_USER_TYPE)) {
            menuList = sysMenuMapper.selectMenuAll();
        } else {
            menuList = sysMenuMapper.selectMenuAllByUserId(sysUser.getId());
        }
        sysUser.setMenuList(menuList);

        return sysUser;
    }
}
